<template>
  <div  style="padding-top:100px">
    <div class="app-title-container title-position">
      <modules-title titleName="菜单管理">
        <template slot="btn">
          <el-button
            type="primary"
            icon="el-icon-plus"
            v-hasPermi="{v:['sys:menu:add']}"
            size="mini"
            @click="handleAdd()"
            >新增</el-button
          >
        </template>
      </modules-title>
    </div>
    <div style="padding:20px;">
      <el-form :inline="true">
        <el-form-item label="菜单名称">
          <el-input
            v-model="menuName"
            placeholder="请输入菜单名称"
            clearable
            size="small"
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>
        <el-form-item label="状态" style="margin-left:40px">
          <el-select
            v-model="menu_status"
            placeholder="菜单状态"
            clearable
            size="small"
            @change="handleQuery"
          >
            <el-option
              v-for="(item, index) in values"
              :key="index"
              :label="item.label"
              :value="item.index"
            />
          </el-select>
        </el-form-item>
        <el-form-item style="margin-left:40px">
          <el-button
            type="primary"
            icon="el-icon-search"
            size="small"
            @click="handleQuery"
            >搜索</el-button
          >
          <el-button
            icon="el-icon-refresh"
            plain
            size="small"
            @click="resetQuery"
            >重置</el-button
          >
        </el-form-item>
      </el-form>
      <el-table
        size="medium"
        border
        :data="menuList"
        row-key="_id"
        :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
      >
        <el-table-column
          prop="menu_name"
          label="菜单名称"
          align="center"
          :show-overflow-tooltip="true"
          width="160"
        ></el-table-column>
        <el-table-column prop="icon" label="图标" align="center" width="100">
          <template slot-scope="scope">
            <svg-icon :icon-class="scope.row.icon" />
          </template>
        </el-table-column>
        <el-table-column
          prop="menu_type"
          label="菜单类型"
          align="center"
          :show-overflow-tooltip="true"
        >
          <template slot-scope="scope">
            <span v-if="scope.row.menu_type == 'F'"
              ><i class="el-icon-s-unfold" style="margin-right: 4px"></i
              >目录</span
            >
            <span v-if="scope.row.menu_type == 'M'"
              ><i class="el-icon-menu" style="margin-right: 4px"></i>菜单</span
            >
            <span v-if="scope.row.menu_type == 'B'"
              ><i class="el-icon-eleme" style="margin-right: 4px"></i>按钮</span
            >
          </template>
        </el-table-column>
        <el-table-column
          prop="sort"
          align="center"
          label="显示顺序"
          :show-overflow-tooltip="true"
        ></el-table-column>
        <el-table-column
          prop="menu_code"
          align="center"
          label="权限标识"
          :show-overflow-tooltip="true"
        ></el-table-column>
        <el-table-column prop="menu_status" align="center" label="状态">
          <template slot-scope="scope">
            <span v-if="scope.row.menu_status == 1" class="status-color6"
              >正常</span
            >
            <span v-if="scope.row.menu_status == -1" class="status-color1"
              >停用</span
            >
          </template>
        </el-table-column>
        <el-table-column
          label="操作"
          align="center"
          class-name="small-padding fixed-width"
        >
          <template slot-scope="scope">
            <el-button
              size="medium"
              type="text"
              icon="el-icon-edit"
              v-hasPermi="{v:['sys:menu:edit']}"
              @click="handleUpdate(scope.row)"
              >修改</el-button
            >

            <el-button
              size="medium"
              type="text"
              icon="el-icon-plus"
              v-hasPermi="{v:['sys:menu:add']}"
              @click="handleAdd(scope.row)"
              >新增</el-button
            >

            <el-button
              class="text-btn-red"
              size="medium"
              type="text"
              icon="el-icon-delete"
              v-hasPermi="{v:['sys:menu:delete']}"
              @click="handleDelete(scope.row)"
              >删除</el-button
            >
          </template>
        </el-table-column>
      </el-table>
    </div>
    <el-dialog
      :title="title"
      :visible.sync="open"
      width="600px"
      append-to-body
      :close-on-click-modal="false"
      :before-close="cancel"
    >
      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
        <el-row>
          <el-col :span="24">
            <el-form-item label="上级菜单">
              <el-select
                v-model="form.parent_id"
                placeholder="上级菜单"
                clearable
                size="small"
                style="width: 100%"
                @change="onChange"
              >
                <el-option
                  v-for="(item, index) in menuOptions"
                  :key="index"
                  :label="item.menu_name"
                  :value="item._id"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="菜单类型" prop="menuType">
              <el-radio-group
                v-model="form.menuType"
                :disabled="disabled"
                @change="changeType()"
              >
                <el-radio label="0">目录</el-radio>
                <el-radio label="1">菜单</el-radio>
                <el-radio label="2">按钮</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item v-if="form.menuType != 2" label="菜单图标">
              <el-popover
                placement="bottom-start"
                width="460"
                trigger="click"
                @show="$refs['iconSelect'].reset()"
              >
                <IconSelect ref="iconSelect" @selected="selected" />
                <el-input
                  slot="reference"
                  v-model="form.icon"
                  placeholder="点击选择图标"
                  readonly
                >
                  <svg-icon
                    v-if="form.icon"
                    slot="prefix"
                    :icon-class="form.icon"
                    class="el-input__icon"
                    style="height: 32px; width: 16px"
                  />
                  <i
                    v-else
                    slot="prefix"
                    class="el-icon-search el-input__icon"
                  />
                </el-input>
              </el-popover>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="菜单名称" prop="menu_name">
              <el-input v-model="form.menu_name" placeholder="请输入菜单名称" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="显示排序" prop="sort">
              <el-input-number
                v-model="form.sort"
                controls-position="right"
                :min="1"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <div v-if="form.menuType == 0">
            <el-row>
              <el-col :span="12">
                <el-form-item label="权限标识" prop="menu_code">
                  <el-input v-model="form.menu_code" placeholder="请输入权限标识" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item
                  label="路由地址"
                  prop="path"
                >
                  <el-input v-model="form.path" placeholder="请输入路由地址" />
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="12">
                <el-form-item label="菜单状态">
                  <el-radio-group v-model="form.status">
                    <el-radio label="1">正常</el-radio>
                    <el-radio label="-1">停用</el-radio>
                  </el-radio-group>
                </el-form-item>
              </el-col>
            </el-row>
        </div>
        <div v-if="form.menuType == 1">
          <el-row>
            <el-col :span="12">
              <el-form-item label="权限标识" prop="menu_code">
                <el-input v-model="form.menu_code" placeholder="请输入权限标识" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="api" prop="api">
                <el-cascader
                  v-model="form.api"
                  :options="apiList"
                  placeholder="请选择API"
                  :show-all-levels="false"
                  @change="onChangeApi()"
                  collapse-tags
                  :props="{ multiple: true, label: 'api_name', value: '_id' }"
                >
                </el-cascader>
              </el-form-item>
            </el-col>
             <el-col :span="12">
              <el-form-item label="路由地址" prop="path">
                <el-input v-model="form.path" placeholder="请输入路由地址" />
              </el-form-item>
            </el-col> 
             <el-col :span="12">
              <el-form-item label="组件地址" prop="component">
                <el-input v-model="form.component" placeholder="请输入组件地址" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
              <el-form-item label="菜单状态">
                <el-radio-group v-model="form.status">
                  <el-radio label="1">正常</el-radio>
                  <el-radio label="-1">停用</el-radio>
                </el-radio-group>
              </el-form-item>
            </el-col>
          </el-row>
        </div>
        <div v-if="form.menuType == 2">
            <el-row>
            <el-col :span="12">
              <el-form-item label="权限标识" prop="menu_code">
                <el-input v-model="form.menu_code" placeholder="请输入权限标识" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="api" prop="api">
                <el-cascader
                  v-model="form.api"
                  :options="apiList"
                  placeholder="请选择API"
                  :show-all-levels="false"
                  @change="onChangeApi()"
                  collapse-tags
                  :props="{ multiple: true, label: 'api_name', value: '_id' }"
                >
                </el-cascader>
              </el-form-item>
            </el-col>
          </el-row>
        </div>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button plain @click="cancel">取 消</el-button>
        <el-button type="primary" @click="submitForm">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import {
  menuList,
  creatMenu,
  updateMenu,
  deleteMenu,
  apiList,
} from "@/api/authorization";
import IconSelect from "@/components/IconSelect";
export default {
  components: { IconSelect },
  data() {
    return {
      disabled: false,
      menuName: "",
      menu_status: "",
      values: [
        {
          index: 1,
          label: "正常",
        },
        {
          index: -1,
          label: "停用",
        },
      ],
      loading: true,
      menuList: [],
      title: "",
      open: false,
      form: {
        menu_name: "",
        menu_code: "",
        component:'',
        parent_id: "0",
        menuType: "0",
        icon: "",
        sort: "",
        path: "",
        status: "1",
        api: [],
      },
      // 表单校验
      rules: {
        menu_name: [
          { required: true, message: "菜单名称不能为空", trigger: "blur" },
        ],
        menu_code: [
          { required: true, message: "权限标识不能为空", trigger: "blur" },
        ],
        component: [
          { required: true, message: "组件地址不能为空", trigger: "blur" },
        ],
        api:[
          {required: false, message: "api不能为空", trigger: "change"}
        ],
        sort: [
          {
            required: true,
            validator: (rule, value, callback) => {
              if (/^(?:[1-9]\d*|0)$/.test(value) == false) {
                callback(new Error("请输入显示顺序,且为正整数"));
              } else {
                callback();
              }
            },
            trigger: "blur",
          },
          // { required: true, message: "菜单顺序不能为空", trigger: "blur" },
        ],
        path: [
          { required: true, message: "路由地址不能为空", trigger: "blur" },
        ],
      },
      value: "",
      options: [],
      menuOptions: [
        {
          _id: "0",
          menu_name: "主目录",
        },
      ],
      id: "",
      apiList: [],
      api: [],
    };
  },
  //是计算属性，也可以理解为一个方法。
  computed: {},
  //属性是手动定义的所需监听的值
  watch: {},
  //生命周期 - 创建完成（访问当前this实例）
  created() {
    this.getMenuList();
    this.getApiList();
  },
  //生命周期 - 挂载完成（访问DOM元素）
  mounted() {},
  //是Vue实例对象上绑定的方法，供当前Vue组件作用域内使用，未调用不会执行，只执行逻辑，返回值可有可无
  methods: {
    getApiList() {
      apiList().then((res) => {
        if (res.code == 200) {
          this.apiList = res.data;
        }
      });
    },
    onChangeApi() {
      console.log(this.form.api);
      this.api = [];
      let arrId = [];
      for (let i = 0; i < this.form.api.length; i++) {
        arrId.push(this.form.api[i][1]);
      }
      console.log(arrId);
      apiList().then((res) => {
        if (res.code == 200) {
          this.apiList = res.data;
          this.apiList.forEach((item) => {
            if (item.children != null) {
              item.children.forEach((itm) => {
                for (let j = 0; j < arrId.length; j++) {
                  if (itm._id == arrId[j]) {
                    let obj = {
                      id: itm._id,
                      method: itm.api_method,
                      url: itm.api_url,
                    };
                    console.log(obj);
                    this.api.push(obj);
                  }
                }
              });
            }
          });
          console.log(this.api);
        }
      });
    },
    // 选择图标
    selected(name) {
      console.log(name);
      this.form.icon = name;
    },
    onChange() {
      console.log(this.form.parent_id);
    },
    //选择类型
    changeType() {
      // console.log(this.form.menuType);
      // this.form.parent_id=''
      this.$refs.form.clearValidate()
      // this.$refs.form.validateField("path");
      this.getMenuList();
    },
    getMenuList() {
      let data = {
        menu_name: this.menuName,
        menu_status: Number(this.menu_status),
      };
      menuList(data).then((res) => {
        console.log(res.data);
        if (res.code == 200) {
          if(res.data!=null){
            this.menuList = res.data;
            console.log(this.menuList);
            // this.menuOptions = res.data
            if (this.form.menuType == "2") {
              this.menuOptions = [];
              let arr = [];
              res.data.forEach((item) => {
                if (item.menu_type == "M") {
                  arr.push(item);
                }
                if (item.children) {
                  item.children.forEach((itm) => {
                    if (itm.menu_type == "M") {
                      arr.push(itm);
                    }
                  });
                }
                this.menuOptions = arr;
                this.form.parent_id = this.menuOptions[0]._id;
                console.log(this.menuOptions);
              });
            } else if (this.form.menuType == "1") {
              this.menuOptions = [
                {
                  _id: "0",
                  menu_name: "主目录",
                },
              ];
              res.data.forEach((item) => {
                if (item.menu_type == "F") {
                  this.menuOptions.push(item);
                }
                // if(item.children&&item.menu_type=='F'){
                //   this.menuOptions.push(item)
                // }
              });
              console.log(this.menuOptions);
              // this.menuOptions = this.menuOptions.concat(res.data)
              this.form.parent_id = this.menuOptions[0]._id;
            } else {
              this.menuOptions = [
                {
                  _id: "0",
                  menu_name: "主目录",
                },
              ];
              this.form.parent_id = this.menuOptions[0]._id;
            }
          }
        }
      });
    },
    resetQuery() {
      this.menuName = "";
      this.menu_status = "";
      this.getMenuList();
    },
    handleQuery() {
      if (this.menuName != "") {
        let that = this;
        let data = {
          menu_name: that.menuName,
          menu_status: Number(that.menu_status),
        };
        menuList(data).then((res) => {
          console.log(res.data);
          if (res.code == 200) {
            if(res.data!=null){
              that.menuList = res.data;
            // that.menuList = that.treeData(that.menuList,'_id','parent_id')
              that.menuList = that.setTreeData(that.menuList);
              console.log(that.menuList);
            }else{
              that.menuList = [];
            }
          }
        });
      } else {
        this.getMenuList();
      }
    },
    setTreeData(arr) {
      // 删除所有的children,以防止多次调用
      arr.forEach(function (item) {
        delete item.children;
      });
      let map = {}; //构建map
      arr.forEach((i) => {
        map[i._id] = i; //构建以id为键 当前数据为值
      });
      let treeData = [];
      arr.forEach((child) => {
        const mapItem = map[child.parent_id]; //判断当前数据的parentId是否存在map中
        if (mapItem) {
          //存在则表示当前数据不是最顶层的数据
          //注意： 这里的map中的数据是引用了arr的它的指向还是arr,当mapItem改变时arr也会改变，踩坑点
          (mapItem.children || (mapItem.children = [])).push(child); //这里判断mapItem中是否存在child
        } else {
          //不存在则是顶层数据
          treeData.push(child);
        }
      });
      return treeData;
    },
    //重置表单
    reset() {
      this.form = {
        menu_name: "",
        menu_code: "",
        component:"",
        parent_id: "0",
        menuType: "0",
        icon: "",
        sort: "",
        path: "",
        status: "1",
        api: [],
      };
      // this.resetForm("form");
    },
    handleAdd(row) {
      console.log(row);
      this.open = true;
      this.title = "添加菜单";
      this.disabled = false;
      this.form.menu_name = "";
      this.form.menu_code = "";
      this.form.sort = "";
      this.form.icon = "";
      if (row) {
        let data = {
          menu_name: "",
          menu_status: 0,
        };
        menuList(data).then((res) => {
          console.log(res.data);
          if (res.code == 200) {
            if (row.menu_type == "F") {
              this.form.menuType = "0";
              this.menuOptions = [
                {
                  _id: "0",
                  menu_name: "主目录",
                },
              ];
              this.form.parent_id = row.parent_id;
            } else if (row.menu_type == "M") {
              this.form.menuType = "1";
              this.menuOptions = [
                {
                  _id: "0",
                  menu_name: "主目录",
                },
              ];
              res.data.forEach((item) => {
                if (item.menu_type == "F") {
                  this.menuOptions.push(item);
                }
              });
              this.form.parent_id = row.parent_id;
            } else {
              this.form.menuType = "2";
              this.menuOptions = [];
              let arr = [];
              res.data.forEach((item) => {
                if (item.menu_type == "M") {
                  arr.push(item);
                }
                if (item.children) {
                  item.children.forEach((itm) => {
                    if (itm.menu_type == "M") {
                      arr.push(itm);
                    }
                  });
                }
                this.menuOptions = arr;
                this.form.parent_id = row.parent_id;
              });
            }
          }
        });
        // if(row.menu_type=='F'){
        //   this.form.menuType='0'
        //   this.menuOptions=[
        //       {
        //         _id:'0',
        //         menu_name:'主目录'
        //       }
        //     ]
        // this.form.parent_id = this.menuOptions[0]._id
        // }else if(row.menu_type=='M'){
        //   this.form.menuType='1'
        //   this.menuOptions = this.menuList
        //   this.form.parent_id = row.parent_id
        // }else{
        //   this.form.menuType='2'
        //   this.menuOptions = this.menuList
        //   this.form.parent_id = row.parent_id
        // }
      }
    },
    handleUpdate(row) {
      this.open = true;
      this.title = "修改菜单";
      this.disabled = true;
      this.id = row._id;
      this.form.menu_name = row.menu_name;
      this.form.menu_code = row.menu_code;
      this.form.component = row.component;
      this.form.sort = row.sort;
      this.form.status = String(row.menu_status);
      this.form.icon = row.icon;
      this.form.path = row.path;
      if (row.menu_type == "F") {
        this.form.menuType = "0";
      } else if (row.menu_type == "M") {
        this.form.menuType = "1";
      } else {
        this.form.menuType = "2";
      }
      if (row.api) {
        let arrList = [];
        row.api.forEach((item) => {
          let arr = [];
          this.apiList.forEach((itm) => {
            if (itm.children) {
              itm.children.forEach((it) => {
                if (item.id == it._id) {
                  arr.push(it.parent_id);
                  arr.push(item.id);
                }
              });
            }
          });
          arrList.push(arr);
        });
        this.form.api = arrList;
      }
      let data = {
        menu_name: "",
        menu_status: 0,
      };
      menuList(data).then((res) => {
        console.log(res.data);
        if (res.code == 200) {
          if (this.form.menuType == "2") {
            this.menuOptions = [];
            let arr = [];
            res.data.forEach((item) => {
              if (item.menu_type == "M") {
                arr.push(item);
              }
              if (item.children) {
                item.children.forEach((itm) => {
                  if (itm.menu_type == "M") {
                    arr.push(itm);
                  }
                });
              }
              this.menuOptions = arr;
              this.form.parent_id = row.parent_id;
            });
          } else if (this.form.menuType == "1") {
            this.menuOptions = [
              {
                _id: "0",
                menu_name: "主目录",
              },
            ];
            res.data.forEach((item) => {
              if (item.menu_type == "F") {
                this.menuOptions.push(item);
              }
            });
            // this.menuOptions = this.menuOptions.concat(res.data)
            this.form.parent_id = row.parent_id;
          } else {
            this.menuOptions = [
              {
                _id: "0",
                menu_name: "主目录",
              },
            ];
            this.form.parent_id = row.parent_id;
          }
        }
      });
      console.log(row.parent_id);
      // this.form.parent_id = row.parent_id
    },
    handleDelete(row) {
      this.$confirm(
        '是否确认删除名称为"' + row.menu_name + '"的菜单项?',
        "警告",
        {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        }
      )
        .then(function () {
          // deleteMenu(row._id).then(res=>{
          //   if(res.code==200){
          //     this.$message.success('删除成功')
          //     this.getMenuList()
          //   }else{
          //     this.$message.success(res.msg)
          //   }
          // })
          // return delMenu(row.id);
        })
        .then(() => {
          deleteMenu(row._id).then((res) => {
            if (res.code == 200) {
              this.$message.success("删除成功");
              this.getMenuList();
            }else{
                this.$message.error(res.msg)
              }
          });
          // this.getList();
          // this.msgSuccess("删除成功");
        })
        .catch(function () {});
    },
    submitForm() {
      console.log(this.form)
      let type = "";
      if (this.form.menuType == "0") {
        type = "F";
      } else if (this.form.menuType == "1") {
        type = "M";
      } else {
        type = "B";
      }
      this.$refs.form.validate((valid) => {
        if (valid) {
          let data = {
            menu_name: this.form.menu_name,
            menu_code: this.form.menu_code,
            component:this.form.component,
            menu_type: type,
            icon: this.form.icon,
            menu_status: Number(this.form.status),
            sort: this.form.sort,
            parent_id: this.form.parent_id,
            api: this.api,
            path: this.form.path,
          };
          if (this.title == "添加菜单") {
            creatMenu(data).then((res) => {
              if (res.code == 200) {
                this.open = false;
                this.getMenuList();
                this.reset();
              }else{
                this.$message.error(res.msg)
              }
            });
          } else {
            updateMenu(this.id, data).then((res) => {
              if (res.code == 200) {
                this.open = false;
                this.getMenuList();
                this.reset();
              }else{
                this.$message.error(res.msg)
              }
            });
          }
        }
      });
    },
    cancel() {
      this.reset();
      this.open = false;
      this.$refs.form.clearValidate()
    },
  },
};
</script>
<style scoped>
/* @import url(); 引入css类 */
</style>
